package pt.compflow.tools;

import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// http://stackoverflow.com/questions/2248131/handling-exceptions-from-java-executorservice-tasks

/**
 * Custom ThreadPoolExecutor that logs throwed exceptions in executed runnables
 * It uses a LinkedBlockungQueue to handle runnables
 * @author Nuno Luz
 *
 */
public class EngineThreadPoolExecutor extends ThreadPoolExecutor {
	
	private static final Logger LOG = LoggerFactory.getLogger(EngineThreadPoolExecutor.class);
	
	public EngineThreadPoolExecutor(int startingThreads, int maxThreads) {
		super(startingThreads, // core threads
				maxThreads, // max threads
				1, // timeout
				TimeUnit.MINUTES, // timeout units
				new LinkedBlockingQueue<Runnable>() // work queue
		);
	}

	protected void afterExecute(Runnable r, Throwable t) {
		super.afterExecute(r, t);
		if (t == null && r instanceof Future<?>) {
			try {
				Future<?> future = (Future<?>) r;
				if (future.isDone())
					future.get();
			} catch (CancellationException ce) {
				t = ce;
			} catch (ExecutionException ee) {
				t = ee.getCause();
			} catch (InterruptedException ie) {
				Thread.currentThread().interrupt(); // ignore/reset
			}
		}
		if (t != null)
			LOG.error("Exception in ThreadPool Task", t);
	}

}